package com.supplychainapi.service.impl;

import com.alibaba.fastjson.JSON;
import com.supplychainapi.dao.prod.TbaddrMapper;
import com.supplychainapi.domain.address.Address;
import com.supplychainapi.model.Tbaddr;
import com.supplychainapi.service.RedisService;
import com.supplychainapi.service.TbaddrService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class TbaddrServiceImpl implements TbaddrService {
    @Autowired
    private TbaddrMapper tbaddrMapper;
    @Autowired
    private RedisService redisService;

    private static String REDIS_CACHE_ADDRESS = "REDIS_CACHE_ADDRESS";

    @Override
    public List<Address> getAll() {
        String addrJson = redisService.get(REDIS_CACHE_ADDRESS);
        if (addrJson != null && !Objects.equals(addrJson, "")) {
            return JSON.parseArray(addrJson, Address.class);
        }
        List<Tbaddr> tbaddrs = tbaddrMapper.selectAll();

        List<Address> addresses = tbaddrs.stream()
                .map(d -> new Address()
                        .setPid(d.getFiParentid())
                        .setValue(d.getFiId())
                        .setLabel(d.getFsAreaname())
                        .setLevel(d.getFiLevel()))
                .collect(Collectors.toList());

        Map<Integer, List<Address>> map = addresses.stream().collect(Collectors.groupingBy(Address::getPid));

        List<Address> list = addresses.stream()
                .filter(addr -> addr.getPid() == 0)
                .map(addr -> setChildren(addr, map))
                .collect(Collectors.toList());
        redisService.set(REDIS_CACHE_ADDRESS, JSON.toJSONString(list));
        return list;
    }

    private Address setChildren(Address address, Map<Integer, List<Address>> map) {
        if (address.getPid() == 0 && address.getValue() == 0) {
            return address.setChildren(Collections.emptyList());
        }
        List<Address> children = map.get(address.getValue());
        if ((children != null) && (children.size() > 0)) {
            children = children.stream().map(child -> setChildren(child, map)).collect(Collectors.toList());
        } else {
            children = Collections.emptyList();
        }
        address.setChildren(children);
        return address;
    }
}
